<?php

namespace app\service;

use app\model\User;
use app\model\UserOauth;
use app\model\UserDevice;
use app\model\UserLog;
use Exception;

class AuthService
{
    /**
     * 用户注册
     */
    public function register($data)
    {
        // 检查用户名/手机号/邮箱是否已存在
        if (User::checkLoginExists($data['login'])) {
            throw new Exception('用户名、手机号或邮箱已存在');
        }

        // 创建用户
        $userData = [
            'nickname' => $data['nickname'] ?? '',
            'password' => $data['password'],
        ];

        // 判断登录方式
        if (filter_var($data['login'], FILTER_VALIDATE_EMAIL)) {
            $userData['email'] = $data['login'];
        } elseif (preg_match('/^1[3-9]\d{9}$/', $data['login'])) {
            $userData['phone'] = $data['login'];
        } else {
            $userData['username'] = $data['login'];
        }

        $user = User::create($userData);

        // 记录注册日志
        UserLog::record($user->id, 'register', '用户注册');

        return $user;
    }

    /**
     * 用户登录
     */
    public function login($login, $password, $deviceInfo = [])
    {
        // 查找用户
        $user = User::findByLogin($login);
        if (!$user) {
            throw new Exception('用户不存在');
        }

        // 验证密码
        if (!$user->checkPassword($password)) {
            throw new Exception('密码错误');
        }

        // 检查用户状态
        if ($user->status != 1) {
            throw new Exception('账号已被禁用');
        }

        // 更新最后登录时间
        $user->updateLastLogin();

        // 注册/更新设备
        if (!empty($deviceInfo)) {
            $this->registerDevice($user->id, $deviceInfo);
        }

        // 生成JWT Token
        $payload = [
            'user_id' => $user->id,
            'login_type' => 'password',
        ];
        $token = generateJWT($payload);

        // 记录登录日志
        UserLog::record($user->id, 'login', '用户登录');

        return [
            'user' => $user,
            'token' => $token,
        ];
    }

    /**
     * 微信登录
     */
    public function wechatLogin($code, $platform = 'mini', $deviceInfo = [])
    {
        $wechatService = new WechatService();
        $userInfo = $wechatService->getUserInfo($code, $platform);

        return $this->oauthLogin('wechat', $userInfo, $deviceInfo);
    }

    /**
     * 支付宝登录
     */
    public function alipayLogin($authCode, $deviceInfo = [])
    {
        $alipayService = new AlipayService();
        $userInfo = $alipayService->getUserInfo($authCode);

        return $this->oauthLogin('alipay', $userInfo, $deviceInfo);
    }

    /**
     * 抖音登录
     */
    public function douyinLogin($code, $deviceInfo = [])
    {
        $douyinService = new DouyinService();
        $userInfo = $douyinService->getUserInfo($code);

        return $this->oauthLogin('douyin', $userInfo, $deviceInfo);
    }

    /**
     * 第三方登录统一处理
     */
    private function oauthLogin($platform, $userInfo, $deviceInfo = [])
    {
        // 先通过openid查找
        $oauth = UserOauth::findByPlatformOpenid($platform, $userInfo['openid']);

        if ($oauth) {
            // 已绑定用户，直接登录
            $user = $oauth->user;
        } else {
            // 尝试通过unionid查找
            if (!empty($userInfo['unionid'])) {
                $oauth = UserOauth::findByPlatformUnionid($platform, $userInfo['unionid']);
                if ($oauth) {
                    // 找到相同unionid的用户，创建新的oauth记录
                    $this->createOauthRecord($oauth->user_id, $platform, $userInfo);
                    $user = $oauth->user;
                } else {
                    // 创建新用户
                    $user = $this->createUserFromOauth($platform, $userInfo);
                }
            } else {
                // 创建新用户
                $user = $this->createUserFromOauth($platform, $userInfo);
            }
        }

        // 检查用户状态
        if ($user->status != 1) {
            throw new Exception('账号已被禁用');
        }

        // 更新最后登录时间
        $user->updateLastLogin();

        // 注册/更新设备
        if (!empty($deviceInfo)) {
            $this->registerDevice($user->id, $deviceInfo);
        }

        // 生成JWT Token
        $payload = [
            'user_id' => $user->id,
            'login_type' => 'oauth',
            'platform' => $platform,
        ];
        $token = generateJWT($payload);

        // 记录登录日志
        UserLog::record($user->id, 'login', "第三方登录({$platform})");

        return [
            'user' => $user,
            'token' => $token,
        ];
    }

    /**
     * 从第三方信息创建用户
     */
    private function createUserFromOauth($platform, $userInfo)
    {
        $userData = [
            'nickname' => $userInfo['nickname'] ?? "用户" . rand(1000, 9999),
            'avatar' => $userInfo['avatar'] ?? '',
        ];

        $user = User::create($userData);

        // 创建OAuth记录
        $this->createOauthRecord($user->id, $platform, $userInfo);

        // 记录注册日志
        UserLog::record($user->id, 'register', "第三方注册({$platform})");

        return $user;
    }

    /**
     * 创建OAuth记录
     */
    private function createOauthRecord($userId, $platform, $userInfo)
    {
        return UserOauth::create([
            'user_id' => $userId,
            'platform' => $platform,
            'openid' => $userInfo['openid'],
            'unionid' => $userInfo['unionid'] ?? '',
            'nickname' => $userInfo['nickname'] ?? '',
            'avatar' => $userInfo['avatar'] ?? '',
            'access_token' => $userInfo['access_token'] ?? '',
            'refresh_token' => $userInfo['refresh_token'] ?? '',
            'expires_at' => $userInfo['expires_at'] ?? null,
            'extra_data' => $userInfo['extra_data'] ?? null,
        ]);
    }

    /**
     * 绑定第三方账号
     */
    public function bindOauth($userId, $platform, $code)
    {
        // 检查是否已绑定该平台
        if (UserOauth::checkUserBound($userId, $platform)) {
            throw new Exception('已绑定该平台账号');
        }

        // 获取第三方用户信息
        switch ($platform) {
            case 'wechat':
                $wechatService = new WechatService();
                $userInfo = $wechatService->getUserInfo($code, 'mini');
                break;
            case 'alipay':
                $alipayService = new AlipayService();
                $userInfo = $alipayService->getUserInfo($code);
                break;
            case 'douyin':
                $douyinService = new DouyinService();
                $userInfo = $douyinService->getUserInfo($code);
                break;
            default:
                throw new Exception('不支持的平台');
        }

        // 检查该第三方账号是否已被其他用户绑定
        $existingOauth = UserOauth::findByPlatformOpenid($platform, $userInfo['openid']);
        if ($existingOauth) {
            throw new Exception('该第三方账号已被其他用户绑定');
        }

        // 创建绑定记录
        $oauth = $this->createOauthRecord($userId, $platform, $userInfo);

        // 记录日志
        UserLog::record($userId, 'bind_oauth', "绑定{$platform}账号");

        return $oauth;
    }

    /**
     * 解绑第三方账号
     */
    public function unbindOauth($userId, $platform)
    {
        $oauth = UserOauth::checkUserBound($userId, $platform);
        if (!$oauth) {
            throw new Exception('未绑定该平台账号');
        }

        $oauth->delete();

        // 记录日志
        UserLog::record($userId, 'unbind_oauth', "解绑{$platform}账号");

        return true;
    }

    /**
     * 注册/更新设备
     */
    public function registerDevice($userId, $deviceInfo)
    {
        $deviceId = $deviceInfo['device_id'] ?? generateDeviceId(
            $deviceInfo['platform'] ?? 'unknown',
            $deviceInfo
        );

        $device = UserDevice::findByDeviceId($deviceId);

        if ($device) {
            // 更新设备信息
            $device->updateActive(
                request()->ip(),
                request()->header('user-agent')
            );
        } else {
            // 检查设备数量限制
            if (!UserDevice::checkUserDeviceLimit($userId)) {
                throw new Exception('设备数量已达上限');
            }

            // 创建新设备
            UserDevice::create([
                'user_id' => $userId,
                'device_id' => $deviceId,
                'device_name' => $deviceInfo['device_name'] ?? '',
                'platform' => $deviceInfo['platform'] ?? 'unknown',
                'device_info' => $deviceInfo,
                'encrypt_method' => $deviceInfo['encrypt_method'] ?? 'AES-256-GCM',
                'app_version' => $deviceInfo['app_version'] ?? '',
                'last_active' => date('Y-m-d H:i:s'),
                'ip_address' => request()->ip(),
                'user_agent' => request()->header('user-agent'),
            ]);
        }

        return $deviceId;
    }

    /**
     * 刷新Token
     */
    public function refreshToken($token)
    {
        $payload = verifyJWT($token);
        if (!$payload) {
            throw new Exception('Token无效');
        }

        // 检查用户是否存在且正常
        $user = User::find($payload['user_id']);
        if (!$user || $user->status != 1) {
            throw new Exception('用户不存在或已被禁用');
        }

        // 生成新Token
        $newPayload = [
            'user_id' => $user->id,
            'login_type' => $payload['login_type'],
        ];

        if (isset($payload['platform'])) {
            $newPayload['platform'] = $payload['platform'];
        }

        $newToken = generateJWT($newPayload);

        return $newToken;
    }

    /**
     * 退出登录
     */
    public function logout($userId)
    {
        // 记录退出日志
        UserLog::record($userId, 'logout', '用户退出');

        return true;
    }
}